package cn.learn.mq.core.pubsub;

import cn.hutool.core.util.TypeUtil;
import cn.learn.mq.core.RedisMqTemplate;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import utils.json.JsonUtil;

import java.lang.reflect.Type;

/**
 * @author : 翌擎科技
 * @date : 2022/7/26 16:14
 */
public abstract class AbstractChannelMessageListener<T extends AbstractChannelMessage> implements MessageListener {


    /**
     * 消息类型
     */
    private final Class<T> messageType;
    /**
     * Redis Channel
     */
    private final String channel;

    @Setter
    private RedisMqTemplate redisMqTemplate;

    @SneakyThrows
    protected AbstractChannelMessageListener() {
        this.messageType = getMessageType();
        this.channel = messageType.newInstance().getChannel();
    }

    @SuppressWarnings("unchecked")
    public Class<T> getMessageType() {
        Type type = TypeUtil.getTypeArgument(getClass(), 0);
        if (type == null) {
            throw new IllegalStateException(String.format("类型(%s) 需要设置消息类型", getClass().getName()));
        }
        return (Class<T>) type;
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        T messageObj = JsonUtil.parseObject(message.getBody(), messageType);
        onMessage(messageObj);
    }

    /**
     * 处理消息
     *
     * @param message 消息
     */
    public abstract void onMessage( T message);

    /**
     * 获得 Sub 订阅的 Redis Channel 通道
     *
     * @return channel
     */
    public final String getChannel() {
        return channel;
    }

}
